#include <typescommon.h>
#include <errno.h>
#include <stdarg.h>
#include <genrand.h>

#if 1
#include <protocolProcesser.h>
#include <charQueue.h>
#include <commandList.h>
#include <commandSetReadSN.h>
#include <pthread.h>
#include <threadExcuter.h>
#include <deviceNormalParam.h>
#include <commandReadBaseInform.h>
#include <deviceOperateSN.h>
#include <taskManager.h>
#include <pipeOperate.h>

struct deviceProcessWorkInform
{
    struct protocolProcessorInform devProcesser;
    struct pipeOperateBaseInform recvPip;
    struct pipeOperateBaseInform sendPip;
};
struct deviceProcessWorkInform devPtcWork;
int deviceCommandReceiveRemoteCheck(uint8_t *readbuffer, int readsize, void *userdata)
{
    struct deviceProcessWorkInform *tmpdevice = (struct deviceProcessWorkInform *)userdata;
    if (!tmpdevice)
    {
        logerror("");
        return -1;
    }
    return pipeOperateRead(&tmpdevice->recvPip, readbuffer, readsize);
}
int deviceCommandSendRemoteCheck(const uint8_t *sendbuffer, int sendsize, void *userdata)
{
    struct deviceProcessWorkInform *tmpdevice = (struct deviceProcessWorkInform *)userdata;
    {
        uint8_t tmpshowstring[PROTOCOL_PACK_MAX_SIZE * 2];
        int tmpconvertSize = hexBufferToReadableString((const char *)sendbuffer, sendsize, (char *)tmpshowstring, sizeof(tmpshowstring), 0);
        logdebug("send,size=%d,convet size=%d,hex str=%s", sendsize, tmpconvertSize, tmpshowstring);
    }
    return pipeOperateWrite(&tmpdevice->sendPip, sendbuffer, sendsize);
}

void deviceCommuniteInit()
{
    struct protocolCommandCommunicateInform tmpCommunity;
    struct hashCommandActuatorManage tmpCommandMng;
    hashCommandActuatorInit(&tmpCommandMng, deviceCommandReceiveCallbackBuffer, commandIdMaxSize);
    memcpy(tmpCommunity.deviceSerialNumber, deviceSnString, sizeof(tmpCommunity.deviceSerialNumber));
    tmpCommunity.receiveFunction = deviceCommandReceiveRemoteCheck;
    tmpCommunity.sendFunction = deviceCommandSendRemoteCheck;
    tmpCommunity.userdata = &devPtcWork;
    protocolProcessorInit(&devPtcWork.devProcesser, tmpCommunity, tmpCommandMng);

    {
        char tmpstr[128];
        snprintf(tmpstr, sizeof(tmpstr), "/tmp/p485_%s.pip", getMaxSizeHexStr(deviceSnString).byteStr);
        pipeOperateInit(&devPtcWork.recvPip, tmpstr);
        pipeOperateInit(&devPtcWork.sendPip, "/tmp/p485_FFFFFFFFFFFF.pip");
    }
}
void deviceCommuniteRun()
{
    protocolProcessorRunReceive(&devPtcWork.devProcesser);
}
void deviceCommuniteQuit()
{
}

struct taskDef deviceTaskList[] = {
    TASK_DEFINE(deviceCommuniteInit, deviceCommuniteRun, deviceCommuniteQuit, 10)};
struct taskManageDef deviceTaskMnger = {
    deviceTaskList, ARRAY_LEN(deviceTaskList), 20};


int checkSendSetSnCmd()
{
    uint8_t tmpPackBuffer[PROTOCOL_PACK_MAX_SIZE];
    struct masterStructSetReadSN tmpsetSn;
    struct protocolPackageCommonInform *tmppack = (struct protocolPackageCommonInform *)tmpPackBuffer;
    struct commandCommonStruct *tmpcommand = (struct commandCommonStruct *)tmppack->v3.v3Data;
    generatorRandString_Aa1s(tmpsetSn.setSn, sizeof(tmpsetSn.setSn));

    memset(tmppack->v3.v3DesAddr, 0xff, sizeof(tmppack->v3.v3DesAddr));
    tmpcommand->commandNB = commandIdSetReadSN;
    tmpcommand->commandSN = generateCommandSerial();
    tmpcommand->responseFlag = commandExcuteResultUnkown;
    memcpy(tmpcommand->commandData, &tmpsetSn, sizeof(tmpsetSn));
    tmppack->v3.v3DataSize = PROTOCOL_V3_DATA_SIZE(sizeof(tmpsetSn));
    int tmpflag = processerPackageProtocolData(&devPtcWork.devProcesser, tmpPackBuffer, sizeof(tmpPackBuffer));
    if (tmpflag <= 0)
    {
        logerror("");
        return -1;
    }
    {
        uint8_t tmpshowstring[PROTOCOL_PACK_MAX_SIZE * 2];
        int tmpconvertSize = hexBufferToReadableString((const char *)tmpPackBuffer, tmpflag, (char *)tmpshowstring, sizeof(tmpshowstring), 0);
        logdebug("send,size=%d,convet size=%d,hex str=%s", tmpflag, tmpconvertSize, tmpshowstring);
    }
    pipeOperateWrite(&devPtcWork.recvPip, tmpPackBuffer, tmpflag);
}

int checkSendReadBaseCmd()
{
    uint8_t tmpPackBuffer[PROTOCOL_PACK_MAX_SIZE];
    struct masterStructReadBaseInfo tmpReadBase;
    struct protocolPackageCommonInform *tmppack = (struct protocolPackageCommonInform *)tmpPackBuffer;
    struct commandCommonStruct *tmpcommand = (struct commandCommonStruct *)tmppack->v3.v3Data;

    memcpy(tmppack->v3.v3DesAddr, deviceSnString, sizeof(tmppack->v3.v3DesAddr));
    tmpcommand->commandNB = commandIdReadBaseInfo;
    tmpcommand->commandSN = generateCommandSerial();
    tmpcommand->responseFlag = commandExcuteResultUnkown;
    // memcpy(tmpcommand->commandData, &tmpReadBase, sizeof(tmpReadBase));
    tmppack->v3.v3DataSize = PROTOCOL_V3_DATA_SIZE(sizeof(tmpReadBase));
    int tmpflag = processerPackageProtocolData(&devPtcWork.devProcesser, tmpPackBuffer, sizeof(tmpPackBuffer));
    if (tmpflag <= 0)
    {
        logerror("");
        return -1;
    }
    {
        uint8_t tmpshowstring[PROTOCOL_PACK_MAX_SIZE * 2];
        int tmpconvertSize = hexBufferToReadableString((const char *)tmpPackBuffer, tmpflag, (char *)tmpshowstring, sizeof(tmpshowstring), 0);
        logdebug("send,size=%d,convet size=%d,hex str=%s", tmpflag, tmpconvertSize, tmpshowstring);
    }
    pipeOperateWrite(&devPtcWork.recvPip, tmpPackBuffer, tmpflag);
}

int main()
{
    timerMsDefine(tmpCheckTimer);
    deviceSnReadFormHardware();
    deviceParamReadFromHard(devParamNormalOpt()); // init param
    deviceNormalParamPrint();

    schedulerInit(&deviceTaskMnger);
    //checkSendSetSnCmd();
    do
    {
        schedulerRun(&deviceTaskMnger);
        usleep(20 * 1000);
        if(timerMsRunSec(tmpCheckTimer) >= 5)
        {
            timerMsBegin(tmpCheckTimer);
            //checkSendReadBaseCmd();
        }
    } while (1);
    schedulerQuit(&deviceTaskMnger);
    return 0;
}
#endif

#if 0
#include <deviceNormalParam.h>

struct deviceParameterNormalInformOld
{
    struct
    {
        uint16_t paramSize;
        uint16_t paramCrc;
    };
    uint8_t deviceSerialNumber[DEVICE_SERIAL_NUMBER_SIZE]; // config by broadcast
};

struct deviceParameterNormalInformNew
{
    struct
    {
        uint16_t paramSize;
        uint16_t paramCrc;
    };
    uint8_t deviceSerialNumber[DEVICE_SERIAL_NUMBER_SIZE]; // config by broadcast
    uint8_t device485Addr;                                  // config by broadcast with device serial number
    uint8_t deviceip[4];
};

int main()
{
    struct deviceParameterNormalInformOld tmpparmOld;
    struct deviceParameterNormalInformNew tmpparmNew;
    char *tmpConstStr;
    // struct deviceParameterNormalInform *tmpNormalParam = devNorParmInst();
    logdebug("--------check read");
    deviceParamReadFromHard(devParamNormalOpt());
    deviceNormalParamPrint();
    logdebug("-------check write");
    deviceParamWriteToHard(devParamNormalOpt());
    deviceNormalParamPrint();
    logdebug("-------check modify");
    tmpConstStr = "12345678901234567890123456789012";
    memcpypro(devNorParmInst()->deviceSerialNumber, sizeof(devNorParmInst()->deviceSerialNumber), tmpConstStr, strlen(tmpConstStr));
    devNorParmInst()->device485Addr = 0x02;
    deviceNormalParamPrint();
    logdebug("-------check write new");
    deviceParamWriteToHard(devParamNormalOpt());
    deviceNormalParamPrint();
    logdebug("-------check new data");
    deviceParamReadFromHard(devParamNormalOpt());
    deviceNormalParamPrint();
    logdebug("-------check reset 1");
    deviceParamResetAndSave(devParamNormalOpt(), DEVICE_PARAM_CONFIG_LEVEL_1);
    deviceNormalParamPrint();
    logdebug("-------check reset 0");
    deviceParamResetAndSave(devParamNormalOpt(), DEVICE_PARAM_CONFIG_LEVEL_0);
    deviceNormalParamPrint();

    devNorParmInst()->device485Addr = 0x01;
    tmpConstStr = "ab345678901234567890123456789012";
    memcpypro(tmpparmOld.deviceSerialNumber, sizeof(tmpparmOld.deviceSerialNumber), tmpConstStr, strlen(tmpConstStr));
    tmpparmOld.paramSize = sizeof(tmpparmOld) - offsetof(struct deviceParameterNormalInformOld, deviceSerialNumber);
    tmpparmOld.paramCrc = calculateUint16CrcHash(tmpparmOld.deviceSerialNumber, tmpparmOld.paramSize);
    logdebug("-------check config shorter data");
    logdebug("%d,%d", tmpparmOld.paramSize, tmpparmOld.paramCrc);
    deviceParamOperateConfig(devParamNormalOpt(), &tmpparmOld, 0);
    deviceNormalParamPrint();
    logdebug("-------check write shorter param");
    deviceParamWriteToHard(devParamNormalOpt());
    logdebug("-------check read shorter param");
    deviceParamReadFromHard(devParamNormalOpt());
    deviceNormalParamPrint();

    tmpConstStr = "fffffddddd";
    memcpypro(tmpparmNew.deviceSerialNumber, sizeof(tmpparmNew.deviceSerialNumber), tmpConstStr, strlen(tmpConstStr));
    tmpparmNew.device485Addr = 0x03;
    tmpConstStr = "fffffddddd";
    memcpypro(tmpparmNew.deviceip, sizeof(tmpparmNew.deviceip), tmpConstStr, strlen(tmpConstStr));
    tmpparmNew.paramSize = sizeof(tmpparmNew) - offsetof(struct deviceParameterNormalInformOld, deviceSerialNumber);
    tmpparmNew.paramCrc = calculateUint16CrcHash(tmpparmNew.deviceSerialNumber, tmpparmNew.paramSize);
    logdebug("-------check config longer data");
    logdebug("%d,%d", tmpparmNew.paramSize, tmpparmNew.paramCrc);
    deviceParamOperateConfig(devParamNormalOpt(), &tmpparmNew, 0);
    deviceNormalParamPrint();
    logdebug("-------check write longer param");
    deviceParamWriteToHard(devParamNormalOpt());
    logdebug("-------check read longer param");
    deviceParamReadFromHard(devParamNormalOpt());
    deviceNormalParamPrint();
}
#endif
